
var https = require('https');
var url = require('url');
var fs = require('fs');
var querystring = require('querystring');
var logger = require('./logger');

if (!process.argv[2]) {
	// Handle possible error for the input at running the server
	throw "Undefined port";
}

logger.log('info', 'Initializing server at port: ' + process.argv[2]);

var accnum = 1;
var db = [];

var options = {
  key: fs.readFileSync('bank-key.pem'),
  cert: fs.readFileSync('bank-crt.crt')
};

https.createServer(options, function(request, response) {
  var u = url.parse(request.url);
  console.log("Request for " + u.path + " received from " + request.connection.remoteAddress);
  if (u.pathname == '/' || u.pathname == '') {
    var data = querystring.parse(u.query);
    var json = JSON.parse(data.data);
    
    var validOptionPattern = /^[1-5]$/;
    
    switch (parseInt(json.action)) {
      case 1: // Creating a new account
        var acc = {account:accnum++, quantity:0}
        db.push(acc);
        var rsp = {
          account: acc.account,
          quantity: acc.quantity,
          error: false
        };
        resultJson = JSON.stringify(rsp);
        logger.log('info', 'Answer sent at inserting a new account');
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.write(resultJson);
        response.end();
        break;
        
      case 2: // Checking the balance of an account 
        var acc = findAccount(parseInt(json.account, 10));
        if (acc) {
          logger.log('info', 'Balance inquiry: success for id ' + acc.account);
          
          var rsp = {
              account: acc.account,
              quantity: acc.quantity,
              error: false
          };
        } else {
          logger.log('info', 'Error: Account does not exist');
          
          var rsp = {
              account: 'Error: Account does not exist',
              quantity: 0,
              error: true
          };
        }
        
        resultJson = JSON.stringify(rsp);
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.write(resultJson);
        response.end();
        break;
        
      case 3: // Deposit for an account
				var amount = parseInt(json.quantity);
				var acc = findAccount(parseInt(json.account, 10));
				if (acc) {
          acc.quantity += amount;
          logger.log('info', 'Answer sent at inserting a new account');
          var rsp = {
            account: 'Deposito exitoso para la cuenta: ' + acc.account,
            quantity: 0,
            error: false
          };
				} else {
          logger.log('info', 'Error: Account does not exist');
          var rsp = {
            account: 'Error: Account does not exist',
            quantity: 0,
            error: true
          };
				}
				resultJson = JSON.stringify(rsp);
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.write(resultJson);
        response.end();
				break;
				
			case 4: // Withdraw from an account
				var amount = parseInt(json.quantity);
				var acc = findAccount(parseInt(json.account));
				if (acc) {
          if (acc.quantity >= amount) {
            acc.quantity -= amount;
            var rsp = {
              account: 'Retiro exitoso para la cuenta: ' + acc.account,
              quantity: 0,
              error: false
            };
            logger.log('info', 'Answer sent at inserting a new account');
          } else {
            logger.log('info', 'Error: Not enough balance');
            var rsp = {
              account: 'Error: Not enough balance',
              quantity: 0,
              error: true
            };
          }
				} else {
          logger.log('info', 'Error: Account does not exist');
          var rsp = {
            account: 'Error: Account does not exist',
            quantity: 0,
            error: true
          };
				}
				
				resultJson = JSON.stringify(rsp);
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.write(resultJson);
        response.end();
				break;
			
      case 5: // Perform a Ping
        logger.log('info', 'Ping request arrived');
        var message = 'Ping Success!!! :)';
        var rsp = {
            account: message,
            quantity: 0,
            error: false
        };
        resultJson = JSON.stringify(rsp);
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.write(resultJson);
        response.end();
        break;
        
      default:
        var rsp = {
            account: 'Invalid option',
            quantity: 0,
            error: false
        };
        resultJson = JSON.stringify(rsp);
        response.writeHead(200, {"Content-Type": "text/plain"});
        response.write(resultJson);
        response.end();
        logger.log("error", "Imposible to reach, the option was: " + parseInt(json.action));
        break;
    }
  }
}).listen(parseInt(process.argv[2], 10));

function findAccount(num) {
  for (var i = 0, l = db.length; i < l; i++) {
    var acc = db[i];
    if (acc.account === num) {
      return acc;
    }
  }
  return null;
}
